package com.authine.cloudpivot.ext.service.impl;


import cn.hutool.core.map.MapBuilder;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.authine.cloudpivot.engine.api.facade.SystemManagementFacade;
import com.authine.cloudpivot.engine.api.model.runtime.WorkItemModel;
import com.authine.cloudpivot.engine.api.model.system.RelatedCorpSettingModel;
import com.authine.cloudpivot.engine.domain.organization.User;
import com.authine.cloudpivot.engine.enums.type.OrgSyncType;
import com.authine.cloudpivot.engine.service.organization.UserService;
import com.authine.cloudpivot.ext.domain.oaSendToDo.OaDeleteToDo;
import com.authine.cloudpivot.ext.domain.oaSendToDo.OaResult;
import com.authine.cloudpivot.ext.domain.oaSendToDo.OaSendToDo;
import com.authine.cloudpivot.ext.service.OaToFacade;
import com.authine.cloudpivot.ext.util.LocalHttpUtil;
import com.authine.cloudpivot.web.api.exception.PortalException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.Base64Utils;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;

@Service
@Slf4j
public class OaWorkItemServiceImpl {
    @Value("${cloudpivot.oa.sendTodo:https://testoa.mszq.com/api/sys-notify/sysNotifyTodoRestService/sendTodo}")
    private String sendTodoUrl;
    @Value("${cloudpivot.oa.deleteTodo:https://testoa.mszq.com/api/sys-notify/sysNotifyTodoRestService/deleteTodo}")
    private String deleteTodoUrl;
    @Value("${cloudpivot.oa.setTodoDone:https://testoa.mszq.com/api/sys-notify/sysNotifyTodoRestService/setTodoDone}")
    private String setTodoDoneUrl;
    @Value("${cloudpivot.oa.itemPcUrl:{}/websso/index.html#/form/detail?workitemId={}&workflowInstanceId={}}")
    private String itemPcUrl;
    @Value("${cloudpivot.oa.itemMobileUrl:{}/mobile?corpId=ding8cd30f4e72d2c55f35c2f4657eb6378f&agentId=714770295#/form/detail?workitemId={}&workflowInstanceId={}}")
    private String itemMobileUrl;
    @Value("${cloudpivot.oa.authentic}")
    private String authentic;
    @Value("${cloudpivot.oa.modelName:cloudpivot}")
    private String modelName;

    private static String host;

    private static final String subject = "请审批{}";


    @Autowired
    private UserService userService;

    @Autowired
    SystemManagementFacade systemManagementFacade;
    RestTemplate restTemplate = new RestTemplate(LocalHttpUtil.clientHttpRequestFactory(5,60));


    /**
     *  发送待办
     * @param item
     * @return 0:成功,1:不需要发送,2:重试
     */
    public boolean sendTodo(WorkItemModel item,String oaAppName){
        log.info("\n=============发送oa待办>>>workDTO={}", JSON.toJSONString(item));

        MapBuilder<String, Object> rstBuild = MapBuilder.create(new HashMap<String, Object>()).put("code","1");

        User user = userService.get(item.getParticipant());

        if (user == null){
            log.info("\n==============发送oa待办失败,待办参与者获取失败,参与者用户不存在,Participant:={}",item.getParticipant());
            return false;
        }
        OaSendToDo oaSendToDo = new OaSendToDo(modelName,item.getId(),
                StrUtil.format(subject,item.getInstanceName()),
                getUrl(item.getId(),item.getInstanceId(),itemPcUrl),
                getUrl(item.getId(),item.getInstanceId(),itemMobileUrl),
                1,
                getTargetJsonStr(user),
                DateFormatUtils.format(item.getStartTime(),"yyyy-MM-dd HH:mm:ss"));

        oaSendToDo.setAppName(oaAppName);

        log.info("\n==============发送oa待办 参数: oaSendToDo={}", JSONObject.toJSONString(oaSendToDo));

        return postForEntity(sendTodoUrl, oaSendToDo);
    }

    /**
     *  待办完成
     * @param workItemId
     * @return
     */
    public boolean setTodoDone(String workItemId){
        log.info("\n=============发送oa已办>>>workItemId={}", JSON.toJSONString(workItemId));
        MapBuilder<String, Object> rstBuild = MapBuilder.create(new HashMap<String, Object>()).put("code","1");

        OaDeleteToDo oaDeleteToDo = new OaDeleteToDo(modelName,workItemId, 1);

        log.info("\n==============发送oa已办参数: oaSendToDo={}",JSONObject.toJSONString(oaDeleteToDo));

        return postForEntity(setTodoDoneUrl, oaDeleteToDo );

    }


    /**
     *  删除待办
     * @param workItemId
     * @return
     */
    public boolean deleteToDo(String workItemId){
        log.info("\n=============发送oa待办删除>>>workItemId={}", JSON.toJSONString(workItemId));
        MapBuilder<String, Object> rstBuild = MapBuilder.create(new HashMap<String, Object>()).put("code","1");

        OaDeleteToDo oaDeleteToDo = new OaDeleteToDo(modelName,workItemId, 1);

        log.info("\n==============发送oa待办删除 参数: oaSendToDo={}",JSONObject.toJSONString(oaDeleteToDo));


        return postForEntity(deleteTodoUrl, oaDeleteToDo );

    }

    private boolean postForEntity(String url,Object param){
        HttpHeaders headers = new HttpHeaders();

        String authHeader = "Basic " + Base64Utils.encodeToString(authentic.getBytes(Charset.forName("UTF-8")));
        headers.set("Authorization", authHeader );

        HttpEntity stringHttpEntity = new HttpEntity( param, headers);

        ResponseEntity<OaResult> rest = null;
        OaResult body = null;
        try {
            rest = restTemplate.postForEntity(url, stringHttpEntity, OaResult.class);
            body = rest.getBody();
        } catch (Exception e) {
            StringBuilder msg = new StringBuilder(" 推送oa待办请求失败: ").append(e.getMessage());
            log.info(msg.toString(), e);
            throw new PortalException(-1111L, msg.toString());
        }

        log.info("\n==============发送oa待办操作 响应: rest={}",JSONObject.toJSONString(rest));

        if (body == null){
            log.info("\n==============发送oa待办操作 失败:{}",JSONObject.toJSONString(rest));
            throw new PortalException(-1111L, "response body is null");
        }else if (body.getReturnState() == null || body.getReturnState().intValue() !=2){

            if (body.getMessage() != null && body.getMessage().contains("待办所属人")){
                return true;
            }
            log.info("\n==============发送oa待办操作 失败:{}",JSONObject.toJSONString(rest));
            throw new PortalException(-1111L, JSONObject.toJSONString(rest));
        }

        return true;
    }

    private String getUrl(String workItemId,String instanceId,String url){
        if (StringUtils.isEmpty(host)){
            List<RelatedCorpSettingModel> list = systemManagementFacade.getAllRelatedCorpSettingModel();
            host = list.stream().filter(l -> l.getSyncType() == OrgSyncType.PULL).findFirst().orElseGet(() -> list.get(0)).getPcServerUrl();
        }

        return StrUtil.format(url,host,workItemId,instanceId);
    }

    private  String getTargetJsonStr(User user){
        JSONObject target = new JSONObject();
        target.put("LoginName",user.getUsername());
        return  target.toJSONString();
    }


}
